package model;
import geo2d.color;
import geo2d.pt;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import processing.core.*;
import view.TopicView;

public class Topic {
	Circle disk; 
	public ArrayList<Topic> member; 
	int num; 
	int level;  
	color c; 
	public boolean expand = false; 
	boolean istopic = false; 
	public static PFont[] Arial = new PFont[3]; 
	public static color[] Color =  new color[4]; 
	private Topic(Circle c){
		disk= c; 
		member=null; 
		num=0;  
	}
	public static void setFontandColor(PApplet pa){
		Arial[0] = pa.createFont("ArialMT", 36);
		Arial[1] = pa.createFont("ArialMT", 24); 
		Arial[2] = pa.createFont("ArialMT", 16); 
		Color[2] = color.red1(); 
		Color[3] = color.blue1(); 
		Color[0] = new color(156, 217, 107, 200); 
	    Color[1] = new color(240, 239, 136, 200); 
	}
	public static Topic Root(String label, int w, int h){
		Topic t=new Topic(Circle.Root(w, h, "Topics in Health")); 
		t.level = 0; 
		return t; 
	}
	public Topic addMember(String label, float mr, float dr){
		if (member==null) member = new ArrayList<Topic>();
		Topic child = new Topic(Circle.Random(disk, mr, dr, label)); 
		child.level = this.level+1; 
		member.add(child); 
		num++; 
		return child; 
	}
	public Topic addMember(color co, float mr, float dr){
		if (member==null) member = new ArrayList<Topic>();
		Topic child = new Topic(Circle.Random(disk, mr, dr, null)); 
		child.level = this.level+1; 
		child.c = co; 
		member.add(child); 
		num++; 
		return child;
	}
	public Topic addMember(String label, float mr, boolean topic){
		if (member==null) member = new ArrayList<Topic>();
		Topic child = new Topic(Circle.Random(disk, mr, 0, label)); 
		child.level = this.level+1; 
		child.istopic = topic; 
		member.add(child); 
		num++; 
		return child; 
	}
	public Topic addMember(String label, float mr){
		if (member==null) member = new ArrayList<Topic>();
		Topic child = new Topic(Circle.Random(disk, mr, 0, label)); 
		child.level = this.level+1; 
		member.add(child); 
		num++; 
		return child; 
	}

	public void showColor(PApplet pa){ 
		//for testing
		if (level>0) {
			if (isselect) this.moveWithMouse(pa);
			color.fill(c, pa); 
			disk.show(pa); 
			}
		if (member==null)return; 
		for (Topic t:member){
			t.showColor(pa); 
		}
	}
	public boolean isselect=false; 
	public Topic selectTopic(pt m){
		if (disk.isIn(m)){
			if (istopic) return this; 
			else {
				for (Topic t:member){
					Topic st = t.selectTopic(m); 
					if (st!=null) return st; 
				}
			}
		}
		return null; 
	}
	public void expand(){
		if (istopic) expand = !expand; 
		if (expand) disk.R*=1.5; 
		if (!expand) disk.R/=1.5; 
	}
	public Topic select(pt m){
		if (disk.isIn(m)){
			if (istopic && !expand) return this; 
			if (num >0){
				for (Topic t:member){
					Topic st = t.select(m); 
					if (st!=null) return st; 
				}
			}
			return this; 
		}
		else return null; 
	}
	public void show(PApplet pa){
		if (level>0) {
			if (num==0) color.fill(Color[0], pa);   
			else color.fill(Color[1], pa); 
			disk.show(pa); 
			}
		if (member==null)return; 
		for (Topic t:member){
			t.show(pa); 
		}
	}
	public void showTopics(PApplet pa){
		showTopicDisk(pa); 
		showTopicLabel(pa); 
	}
	private void showTopicDisk(PApplet pa){
		if (istopic) {
			color.fill(Color[3], pa);
			disk.show(pa); 
			if (!expand) return; 
		}
		else if (level==1) {
			color.fill(Color[1], pa);
			disk.show(pa);  
		}
		else if (level>0){
			color.fill(Color[0], pa);
			disk.show(pa);
		}
		if (num>0) for (Topic t:member) t.showTopicDisk(pa);
	}
	public void showTopicLabel(PApplet pa){
		if (istopic) {
			if (expand) pa.fill(200, 200); 
			else pa.fill(0, 180);  
			pa.textFont(Arial[1]);
			disk.showLabel(pa); 
			if (!expand) return; 
		}
		else if (level==1) {
			pa.fill(200, 200);  
			pa.textFont(Arial[0]);
			disk.showLabel(pa);   
		}
		else if (level>0){
			pa.fill(20); 
			pa.textFont(Arial[2]); 
			disk.showLabel(pa);
		}
		if (num>0) for (Topic t:member) t.showTopicLabel(pa);
	}
	public void showWords(PApplet pa){
		if (level>0 && num>0) {
			color.fill(Color[1], pa);
			disk.show(pa); 
		}
		if (num>0) for (Topic t:member) t.showWords(pa); 
		if (level>0 && num==0){
			color.fill(Color[0], pa);
			disk.show(pa); 
			pa.fill(0); 
			pa.textFont(Arial[2]); 
			disk.showLabel(pa); 
		}
	}
	public static void interact(Topic t){
		if ( t.num==0 || t.member==null) return;  
		for (int i=0; i<t.num-1; i++){
			for (int j=i+1; j<t.num; j++){
				Circle.repel(t.member.get(i).disk, t.member.get(j).disk); 
			}
		}
		for (Topic st:t.member){
			interact(st); 
		}
	}
	public void moveWithMouse(PApplet pa){
		this.disk.O.moveWithMouse(pa); 
	}
	
	public static void apply(Topic t){
		if ( t.num==0 || t.member==null) return;
		for (Topic st:t.member){
			st.disk.sink(t.disk);
		}
		for (Topic st:t.member){
			apply(st); 
		}
	}
	public void update(){
		if (isselect) return; 
		interact(this); 
		apply(this); 
	}
	public void grow(){
		if (level>0) disk.grow(level); 
		if (member==null) return; 
		for (Topic st:member){
			st.grow(); 
		}
	}
	public void save(){
		
	}
	public void load(){
		
	}
	

}
